/// 小票数据模型，包含原始小票文本及解析字段
class ReceiptModel {
  /// 原始小票文本
  final String printContent;
  /// 小票分行文本
  final List<String> textLines;
  /// 交易金额
  final String? amount;
  /// 卡号（脱敏）
  final String? cardNumber;
  /// 授权码
  final String? approvalCode;
  /// 商户名称
  final String? merchantName;
  /// 终端号
  final String? terminalId;
  /// 交易ID（通常为流水号或序列号）
  final String? transactionId;
  /// 交易日期
  final String? date;
  /// 交易时间
  final String? time;
  /// 卡品牌
  final String? cardBrand;
  /// AID
  final String? aid;
  /// 流水号/序列号
  final String? sequenceNumber;
  /// 批次号
  final String? batchNumber;
  /// 额外字段
  final Map<String, dynamic> extra;

  ReceiptModel({
    required this.printContent,
    required this.textLines,
    this.amount,
    this.cardNumber,
    this.approvalCode,
    this.merchantName,
    this.terminalId,
    this.transactionId,
    this.date,
    this.time,
    this.cardBrand,
    this.aid,
    this.sequenceNumber,
    this.batchNumber,
    this.extra = const {},
  });

  /// 通过完整小票文本解析生成ReceiptModel实例
  factory ReceiptModel.fromFullText(String fullText) {
    final textLines = fullText
        .split('\n')
        .map((l) => l.trim())
        .where((l) => l.isNotEmpty)
        .toList();

    String? amount,
        cardNumber,
        approvalCode,
        merchantName,
        terminalId,
        transactionId,
        date,
        time,
        cardBrand,
        aid,
        sequenceNumber,
        batchNumber;

    // 批次号提取：优先从小票头部类似'002 24.06.2025 12:29:40  0113'的行中提取最后4位数字
    // 也支持捷克语格式：DÁVKA: 008
    final batchLine = textLines.firstWhere(
      (l) => RegExp(r'^\d{3} \d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}  \d{4}').hasMatch(l) ||
            l.contains('DÁVKA:') || l.contains('Batch:'),
      orElse: () => '',
    );
    if (batchLine.isNotEmpty) {
      // 先尝试从捷克语格式提取：DÁVKA: 008
      var match = RegExp(r'(?:DÁVKA|Batch)\s*:\s*(\d+)', caseSensitive: false).firstMatch(batchLine);
      if (match != null) {
        batchNumber = match.group(1)!.padLeft(4, '0'); // 补齐到4位
      } else {
        // 尝试从英文格式提取：最后4位数字
        match = RegExp(r'(\d{4})\s*$').firstMatch(batchLine);
        if (match != null) {
          batchNumber = match.group(1);
        }
      }
    }

    // 商户名：通常是小票的开头部分
    if (textLines.isNotEmpty) {
      // 寻找第一个不是分隔线、不包含特定关键字的非空行
      // 支持英文和捷克语关键词过滤
      merchantName = textLines.firstWhere(
        (l) =>
            !l.startsWith('---') &&
            !l.toUpperCase().contains("RECEIPT") &&
            !l.toUpperCase().contains("MERCHANT") &&
            !l.toUpperCase().contains("ÚČTENKA") && // 捷克语：收据
            !l.toUpperCase().contains("DÁVKA") && // 捷克语：批次
            !l.toUpperCase().contains("ID.ZAŘÍZENÍ") && // 捷克语：设备ID
            !l.toUpperCase().contains("ČÁSTKA") && // 捷克语：金额
            !l.toUpperCase().contains("SEKVENČNÍ") && // 捷克语：序列
            !l.toUpperCase().contains("AUTORIZAČNÍ") && // 捷克语：授权
            l.trim().length > 4, // 过滤掉太短的行
        orElse: () => textLines.first, // 如果没找到就用第一行
      );
    }

    for (final l in textLines) {
      // 金额匹配：支持英文 "Amount EUR" 和捷克语 "Částka CZK" 等格式
      if (l.contains('Amount EUR') || l.contains('Částka CZK') || 
          l.contains('Částka') || l.contains('Amount')) {
        // 匹配格式：Amount EUR 123.45 或 Částka CZK: 2,15
        final match = RegExp(r'(?:Amount|Částka)\s+(?:EUR|CZK|USD)?\s*:?\s*([\d.,]+)', 
            caseSensitive: false).firstMatch(l);
        if (match != null) {
          amount = match.group(1)?.replaceAll(',', '.');
        }
      }
      
      // 卡号匹配：支持多种格式
      // 格式1: Card: ****1234
      // 格式2: 5450 34** **** 6230 (直接显示卡号，可能有前导空格)
      if (l.contains('Card:') || l.trim().startsWith('Card:')) {
        final match = RegExp(r'\*+(\d{4})').firstMatch(l);
        if (match != null) cardNumber = '************${match.group(1)}';
      } else {
        // 匹配格式：5450 34** **** 6230 或类似格式
        // 匹配模式：数字 + 空格 + 数字 + 星号 + 空格 + 星号 + 空格 + 数字
        final cardMatch = RegExp(r'(\d{4}\s+\d{2}\*+\s+\*+\s+\d{4})').firstMatch(l.trim());
        if (cardMatch != null) {
          final cardStr = cardMatch.group(1)!.replaceAll(RegExp(r'\s+'), '');
          // 提取最后4位数字
          final last4Match = RegExp(r'(\d{4})$').firstMatch(cardStr);
          if (last4Match != null) {
            cardNumber = '************${last4Match.group(1)}';
          }
        }
      }
      
      // 授权码匹配：支持英文和捷克语
      // Approval code: 或 Autorizační kód:
      if (l.contains('Approval code:') || l.contains('Autorizační kód:')) {
        final match = RegExp(r'(?:Approval code|Autorizační kód)\s*:\s*(\S+)', 
            caseSensitive: false).firstMatch(l);
        if (match != null) approvalCode = match.group(1);
      }
      
      // 终端ID匹配：支持英文和捷克语
      // TERMINAL: 或 ID.ZAŘÍZENÍ:
      if (l.contains('TERMINAL:') || l.contains('ID.ZAŘÍZENÍ:')) {
        final match = RegExp(r'(?:TERMINAL|ID\.ZAŘÍZENÍ)\s*:\s*(\d+)', 
            caseSensitive: false).firstMatch(l);
        if (match != null) terminalId = match.group(1);
      }
      
      // AID匹配：支持带冒号和不带冒号的格式
      // 格式1: AID: A0000000041010
      // 格式2: A0000000041010 (单独一行，以A开头，后跟数字和字母)
      if (l.contains('AID:')) {
        final match = RegExp(r'AID\s*:\s*([A-Z0-9]+)', caseSensitive: false).firstMatch(l);
        if (match != null) aid = match.group(1);
      } else {
        // 匹配单独一行的AID格式：A + 数字/字母组合
        final aidMatch = RegExp(r'^A[A-Z0-9]{10,}$').firstMatch(l.trim());
        if (aidMatch != null && aid == null) {
          aid = aidMatch.group(0);
        }
      }
      
      // 序列号匹配：支持英文和捷克语
      // Sequence number: 或 Sekvenční č.:
      if (l.contains('Sequence number:') || l.contains('Sekvenční č.:')) {
        final match = RegExp(r'(?:Sequence number|Sekvenční č\.)\s*:\s*(\d+)', 
            caseSensitive: false).firstMatch(l);
        if (match != null) {
          sequenceNumber = match.group(1);
          transactionId = sequenceNumber; // 使用序列号作为交易ID
        }
      }

      // 日期时间匹配：支持两种格式
      // 格式1: DD.MM.YYYY HH:MM:SS (英文格式)
      // 格式2: DD/MM/YYYY HH:MM:SS (捷克语格式)
      var dateTimeMatch = RegExp(r'(\d{2}\.\d{2}\.\d{4})\s+(\d{2}:\d{2}:\d{2})').firstMatch(l);
      dateTimeMatch ??= RegExp(r'(\d{2}/\d{2}/\d{4})\s+(\d{2}:\d{2}:\d{2})').firstMatch(l);
      if (dateTimeMatch != null) {
        // 统一转换为 DD.MM.YYYY 格式
        final dateStr = dateTimeMatch.group(1)!.replaceAll('/', '.');
        date = dateStr;
        time = dateTimeMatch.group(2);
      }

      // 卡品牌匹配：支持更多格式
      final upperLine = l.toUpperCase().trim();
      if (upperLine == 'VISA' || upperLine == 'MASTERCARD' || 
          upperLine.contains('MC CONTACTLESS') || upperLine.contains('MC ')) {
        if (upperLine.contains('VISA')) {
          cardBrand = 'VISA';
        } else if (upperLine.contains('MC') || upperLine.contains('MASTERCARD')) {
          cardBrand = 'MASTERCARD';
        }
      }
    }

    return ReceiptModel(
      printContent: fullText.trim(),
      textLines: textLines,
      amount: amount,
      cardNumber: cardNumber,
      approvalCode: approvalCode,
      merchantName: merchantName,
      terminalId: terminalId,
      transactionId: transactionId,
      date: date,
      time: time,
      cardBrand: cardBrand,
      aid: aid,
      sequenceNumber: sequenceNumber,
      batchNumber: batchNumber,
      extra: {},
    );
  }

  /// 转为JSON对象，便于序列化
  Map<String, dynamic> toJson() => {
    'textLines': textLines,
    'amount': amount,
    'cardNumber': cardNumber,
    'approvalCode': approvalCode,
    'merchantName': merchantName,
    'terminalId': terminalId,
    'transactionId': transactionId,
    'date': date,
    'time': time,
    'cardBrand': cardBrand,
    'aid': aid,
    'sequenceNumber': sequenceNumber,
    'batchNumber': batchNumber,
    'extra': extra,
    'printContent': printContent,
  };
}
